home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 014 / filesort.arc / FILESORT.BAS (.txt)
Encoding:
GW-BASIC  |  1986-02-19  |  4.7 KB  |  156 lines

  1. 90  REM -------------- A   S O R T / M E R G E    P R O G R A M -------------
  2. 91  REM
  3. 92  REM  Original written by Terry Dettmann, Assoc. Ed of 80 MICRO magazine.
  4. 93  REM  Modifed & adapted to IBM PC by Gerry L. Kilgore
  5. 94  REM
  6. 95  REM --------Define all variables to be integers
  7. 96  REM
  8. 100  DEFINT A-Z
  9. 101  SCREEN 0,0:COLOR 7,0:CLS:PRINT TAB(35) "SORT/MERGE":PRINT:PRINT
  10. 102  LINE INPUT "Enter record length to be sorted ==> ";A$
  11. 103  NR=VAL(A$):IF NR<4 OR NR>254 THEN 102 ELSE NL=8000/NR
  12. 105  REM
  13. 106  REM-----Variables NL, NFL & NX control size of SORT/MERGE
  14. 107  REM-----NL=Max No. of lines in memory; NFL=Max No. file buffers available
  15. 108  REM-----NX=Max No. of temporary files to use
  16. 109  REM
  17. 110  NFL=8: NX=16
  18. 114  REM
  19. 115  REM-------LN$() is the line buffer array
  20. 116  REM-------FF$() is the temporary filename list
  21. 117  REM-------FC$() is the set of files to use to merge
  22. 118  REM
  23. 120  DIM LN$(NL),FF$(NX),FC$(NFL)
  24. 125  REM-------FT$ is the temporary filename root
  25. 126  REM-------FT is the number of the current temporary file
  26. 130  FT$="Temp": FT=0
  27. 135  REM------FNCTR$(X$) prints X$ centered on an 80 character line
  28. 136  REM------FNHDR$(X$) prints a 3 line header
  29. 140  DEF FNCTR$(X$)=STRING$((80-LEN(X$))/2,32)+X$
  30. 150  DEF FNHDR$(X$)=STRING$(80,220)+FNCTR$(X$)+CHR$(13)+STRING$(80,220)
  31. 195  REM
  32. 196  REM - - - - - - - SORT/MERGE DEMO: MAIN PROGRAM - - - - - - - - -
  33. 197  REM
  34. 198  REM----------Get the input and output file names (can be the same)
  35. 199  REM
  36. 200  LINE INPUT "Input file ==> ";FI$: LINE INPUT "Output file ==> ";FO$
  37. 233  PRINT:PRINT "Enter drive number for the sort work files (A,B,C) ==> ";
  38. 235  Z$=INKEY$:IF Z$="" OR Z$=CHR$(13) THEN 235
  39. 236  IF Z$="A" OR Z$="a" OR Z$="B" OR Z$="b" OR Z$="C" OR Z$="c" THEN 240 ELSE PRINT Z$:Z$=":"+Z$
  40. 240  PRINT:PRINT
  41. 245  REM----------Get the input file
  42. 250  OPEN "I",1,FI$
  43. 255  REM----------Read in part of the input file
  44. 260  GOSUB 1000
  45. 265  REM-----------Sort it
  46. 270  GOSUB 2000
  47. 275  REM----------Write it to a temporary file
  48. 280  GOSUB 3000
  49. 285  REM----------If all the data from the input file not read then get more
  50. 290  IF FLG<>1 THEN 260
  51. 295  REM----------Close all files
  52. 300  CLOSE
  53. 305  REM----------Start the merge operation
  54. 310  GOSUB 4000
  55. 315  REM----------Open the files - 1 for output
  56. 316  REM                         - 2-NZ for input
  57. 320  OPEN "O",1,FC$(1):PRINT
  58. 330  PRINT FNCTR$("OUTPUT FILE: "+FC$(1))
  59. 340  FOR I=2 TO NZ
  60. 350  OPEN "I",I,FC$(I)
  61. 360  PRINT FNCTR$("INPUT FILE: "+FC$(I))
  62. 365  REM-----------Get the first line from each file
  63. 370  LINE INPUT #I,LN$(I)
  64. 380  NEXT I:PRINT
  65. 385  REM-----------Choose the smallest line
  66. 390  GOSUB 5000
  67. 395  REM-----------If there is no smallest line then we're done this pass
  68. 400  IF LN$="" THEN 430
  69. 405  REM-----------Put the smalles line to the output file
  70. 410  PRINT #1,LN$:K=K+1':PRINT USING "####> ";K;:PRINT LN$
  71. 420  GOTO 390
  72. 430  CLOSE:PRINT
  73. 434  REM----------Kill old temporary input files
  74. 435  FOR I=2 TO NZ:KILL FC$(I):PRINT FNCTR$("KILLING FILE: "+FC$(I)):NEXT I:PRINT
  75. 440  PRINT:IF FC$(1)<>FO$ THEN EF=1 ELSE EF=0
  76. 445  REM---------If we're not done, then go get the rest
  77. 450  IF EF=1 THEN 310
  78. 460  END
  79. 995  REM
  80. 996  REM - - - - - - - Read from input file - - - - - - - -
  81. 997  REM
  82. 998  REM        FLG is a flag to mark the end of the input file
  83. 999  REM
  84. 1000  FLG=0
  85. 1020  PRINT:PRINT FNCTR$("READING FROM: "+FI$)
  86. 1025  REM-------Read in up to nl lines
  87. 1030  FOR I=1 TO NL
  88. 1040  IF EOF(1) THEN FLG=1: GOTO 1070
  89. 1050  LINE INPUT #1,LN$(I):'PRINT USING "####> ";I;:PRINT LN$(I)
  90. 1060  NEXT I
  91. 1065  IF EOF(1) THEN FLG=1
  92. 1067  REM--------NM is the no. of lines actually read in
  93. 1070  NM=I-1: RETURN
  94. 1995  REM
  95. 1996  REM - - - - - - - - Sort data in memory - - - - - - - - - -
  96. 1997  REM
  97. 1998  REM-----------Set the initial gap
  98. 1999  REM
  99. 2000  GAP=NM
  100. 2015  REM----------If gap gets down to 1, we're done
  101. 2020  IF GAP <= 1 THEN RETURN
  102. 2025  REM----------Look at 1/2 the previous gap
  103. 2030  GAP = INT(GAP/2)
  104. 2035  REM----------Set the swap flag to no swaps made
  105. 2040  FG = 0
  106. 2050  FOR I=1 TO NM-GAP
  107. 2060  IF LN$(I) > LN$(I+GAP) THEN SWAP LN$(I),LN$(I+GAP):FG=1
  108. 2070  NEXT I
  109. 2080  IF FG=1 THEN 2040 ELSE 2020
  110. 2995  REM
  111. 2996  REM - - - - - - Write data to temporay output file - - - - - - -
  112. 2997  REM
  113. 2998  REM---------FT is the current temporary output file
  114. 2999  REM---------Make NF$ the current temporary file name & save it
  115. 3000  FT=FT+1: NF$=FT$+MID$(STR$(FT),2)+Z$: FF$(FT)=NF$: IF FT>=NX THEN FLG=1
  116. 3015  REM---------Write the lines to the temporary file
  117. 3020  OPEN "O",2,NF$: PRINT
  118. 3030  PRINT FNCTR$("TEMPORARY FILE: "+NF$)
  119. 3040  FOR I=1 TO NM:PRINT#2,LN$(I)':PRINT USING "####> ";I;:PRINT LN$(I)
  120. 3045  NEXT I:PRINT
  121. 3050  CLOSE 2
  122. 3060  RETURN
  123. 3993  REM
  124. 3994  REM - - - - - - - Pick output file & input offset
  125. 3995  REM
  126. 3996  REM-----------F1 is 1st file read, F2 is last file read
  127. 3997  REM-----------FF is no. of the intermediate merge file
  128. 3998  REM
  129. 4000  F1=F2+1: F2=F2+NFL-1: FF=(FF+1) MOD 2
  130. 4020  FF$=FT$+"X"+MID$(STR$(FF),2)+Z$
  131. 4030  IF FC$(1)="" THEN 4060
  132. 4040  FC$(2)=FC$(1): F2=F2-1: J=2
  133. 4050  GOTO 4070
  134. 4060  J=1
  135. 4070  IF F2>FT THEN F2=FT
  136. 4080  IF F2=FT THEN FC$(1)=FO$ ELSE FC$(1)=FF$
  137. 4090  FOR I=F1 TO F2: J=J+1
  138. 4100  FC$(J)=FF$(I)
  139. 4110  NEXT I
  140. 4120  NZ=J: K=0
  141. 4130  RETURN
  142. 4995  REM
  143. 4996  REM - - - - - - - - Select smallest input line - - - - - - - - - -
  144. 4997  REM
  145. 5000  FOR I=2 TO NZ: IF LN$(I)<>"" THEN 5050
  146. 5020  NEXT I
  147. 5030  LN$=""
  148. 5040  RETURN
  149. 5050  FC=I: LN$=LN$(I): J=I+1
  150. 5060  IF J>NZ THEN 5100
  151. 5070  FOR I=J TO NZ: IF LN$(I)="" THEN 5090
  152. 5080  IF LN$>LN$(I) THEN LN$=LN$(I): FC=I
  153. 5090  NEXT I
  154. 5100  IF NOT EOF(FC) THEN LINE INPUT #FC,LN$(FC) ELSE LN$(FC)=""
  155. 5110  RETURN
  156.